package evo;

import ids.Sensor;
import ids.SensorType;

import java.io.File;
import java.util.Vector;

import ns2.Topology;
import opt.FitnessFunction;
import util.FileReader;
import util.SSIDException;
import ec.EvolutionState;
import ec.Individual;
import ec.Problem;
import ec.multiobjective.MultiObjectiveFitness;
import ec.simple.SimpleProblemForm;
import ec.util.Parameter;
import ec.vector.BitVectorIndividual;

public class MOOProblemBit extends Problem implements SimpleProblemForm {

	private static final long serialVersionUID = 1L;

	public static final String SENSORFILE = "sensorFile";
	public static final String TRACEFILE = "traceFile";
	public static final String TOPOLOGYFILE = "topologyFile";

	public File sensorFile;
	public File traceFile;
	public File topologyFile;

	public Topology topology;
	public Vector<Sensor> sensors;

	public FitnessFunction fitnessfunction;

	public void setup(final EvolutionState state, final Parameter base) {
		// very important, remember this
		super.setup(state, base);

		this.sensorFile = new File(state.parameters.getString(base
				.push(SENSORFILE), null));
		this.traceFile = new File(state.parameters.getString(base
				.push(TRACEFILE), null));
		this.topologyFile = new File(state.parameters.getString(base
				.push(TOPOLOGYFILE), null));

		FileReader fileReader = null;
		try {
			fileReader = new FileReader(this.traceFile, this.topologyFile,
					this.sensorFile);
			fileReader.readTraceFile();
			fileReader.readTopologyFile();
			fileReader.process();
		} catch (SSIDException e) {
			state.output.fatal(e.getMessage());
		}

		this.topology = fileReader.getTopology();
		this.fitnessfunction = new FitnessFunction();
	}

	@Override
	public void describe(Individual ind, EvolutionState state,
			int subpopulation, int threadnum, int log, int verbosity) {
		// TODO Auto-generated method stub

	}

	@Override
	public void evaluate(EvolutionState state, Individual ind,
			int subpopulation, int threadnum) {
		if (ind.evaluated)
			return;

		if (!(ind instanceof BitVectorIndividual))
			state.output
					.fatal("Whoa!  It's not a BitVectorIndividual!!!", null);

		BitVectorIndividual ind2 = (BitVectorIndividual) ind;
		this.sensors = new Vector<Sensor>();
		int index = 0;

		for (int i = 0; i < ind2.genome.length; i++) {
			if (ind2.genome[i]) {
				Sensor newsensor = Sensor.createSensor(SensorType.ProbeSensor);
				newsensor.id = index++;
				newsensor.efficiency = 6.72f;
				newsensor.monitoringCost = 3f;
				newsensor.deploymentCost = 8f;
				newsensor.setLocation(this.topology.nodes.getNode(i));
				newsensor.run();
				this.sensors.addElement(newsensor);
			}
		}

		this.fitnessfunction.checkContribution(sensors);
		this.fitnessfunction.evaluate(sensors);

		MultiObjectiveFitness mof = (MultiObjectiveFitness) ind2.fitness;
		mof.maximize = false;
		mof.multifitness[0] = this.fitnessfunction.nContributingSensors;
		mof.multifitness[1] = 154 - this.fitnessfunction.detectedAttacks;
		mof.multifitness[2] = this.fitnessfunction.falseAlarms;

		ind2.evaluated = true;
	}
}
